/****************************************************
 * @file: main.c
 * @brief: 处理通信中的不同状态
 * @author: 廖文雄 
 * @date: 2019.07.27
 * @note: 
 ****************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <malloc.h>

#include "communication.h"

int main()
{
    int is_break_outside = FALSE;
    int state = BUILD_FIFO;
    int bag_type = REQUEST;
    char *send_data;
    char *get_data = (char *)malloc(BAG_DATA * sizeof(char));
    int fifo_fd;
    int is_rdwr_success;
    int is_revice_success;
    int res;
    int is_verify;

    while (is_break_outside != TRUE) {
        switch (state) {
            case BUILD_FIFO :
                if (access(FIFO_NAME, F_OK) == -1) {
                    res = mkfifo(FIFO_NAME, 0766);
                    if (res != 0) {
                        break;
                    } else {
                        state = BAG_BUILD;
                        break;
                    }
                }
            case BAG_BUILD :
                send_data = build_data(bag_type);
                if (!send_data) {
                    break;
                } else {
                    state = BAG_SEND;
                    break;
                }
            case BAG_SEND :
                fifo_fd = open(FIFO_NAME, O_WRONLY);
                if (fifo_fd == FALSE) {
                    printf("can't open fifo\n");
                    break;
                }
                is_rdwr_success = write(fifo_fd, send_data,
                                    strlen(send_data));
                if (is_rdwr_success == FALSE) {
                    printf("send error\n");
                    close(fifo_fd);
                    break;
                } else {
                    free(send_data);
                    close(fifo_fd);

                    state = BAG_REVICE;
                    break;
                }
            case BAG_REVICE :
                fifo_fd = open(FIFO_NAME, O_RDONLY);
                if (fifo_fd == FALSE) {
                    printf("can't open fifo\n"); 
                    break;
                }
                is_rdwr_success = read(fifo_fd, get_data, BAG_COMMOND);
                if (is_rdwr_success == FALSE) {
                    printf("revice error\n");
                    close(fifo_fd);
                    break;
                } else {
                    close(fifo_fd);

                    state = BAG_ANALYSIS;
                    break;
                }
            /* 这个和状态转换有关,需要根据自己的状态转换和逻辑来写 */
            case BAG_ANALYSIS :
                /* 分析校验位 */
                is_verify = analysis_verify(get_data);
                /*应答包接收失败，再发一次请求包*/
                /*数据对应的应答包接收失败，再发一次数据*/
                if (is_verify == FALSE) {
                    state = BAG_BUILD;
                    break;
                }

                is_revice_success = analysis_data(get_data);
                if (is_revice_success == FALSE) {
                    /*应答包接收失败，再发一次请求包*/
                    /*数据对应的应答包接收失败，再发一次数据*/
                    state = BAG_BUILD;
                    break;
                } else {
                    /*请求失败，再发一次请求包*/
                    if (bag_type == REQUEST) {
                        if (is_revice_success == FALSE_REQUEST) {
                            state = BAG_BUILD;
                            break;
                        } else if (is_revice_success == RESPONSE) {
                            /* 请求成功，接收到应答包,开始发送数据 */
                            bag_type = PRINT_NORMAL;
                            state = BAG_BUILD;
                            break;
                        } else {
                            /* 请求成功，应答包出错,再发一次请求包 */
                            state = BAG_BUILD;
                            break;
                        }
                    } else if (bag_type == PRINT_NORMAL ||
                                bag_type == PRINT_REVERSE) {
                        /*数据发送失败，再发一次数据*/
                        if (is_revice_success == FALSE_DATA) {
                            state = BAG_BUILD;
                            break;
                        }
                        /*数据发送成功，关机*/
                        if (is_revice_success == ACK_DATA) {
                            state = FINISH;
                            break;
                        }
                    }
                }
            case FINISH :
                is_break_outside = TRUE;
                break;
        }
    }

    return 1;
}